﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Configuration.Provider;

using Job.Core.Common;

namespace Job.Core.Module
{
    /// <summary>
    /// 提供程序服务类，提供所有提供程序的加载及初始化。
    /// </summary>
    public static class ProviderService
    {
        #region Properties

        private static Dictionary<string, object> providers = LoadProviders();

        /// <summary>
        /// 所有加载模块集合(Key为模块Id)。
        /// </summary>
        public static Dictionary<string, object> Providers
        {
            get { return providers; }
        }

        #endregion

        #region Methods

        /// <summary>
        /// 加载所有提供程序。
        /// </summary>
        private static Dictionary<string, object> LoadProviders()
        {
            Dictionary<string, object> mos = new Dictionary<string, object>();

            ModuleProviderConfigSection moduleConfig = ConfigurationManager.GetSection("moduleProvider") as ModuleProviderConfigSection;

            if (moduleConfig == null)
                return mos;

            ProviderSettingsCollection settings = moduleConfig.Providers;

            foreach (ProviderSettings setting in settings)
            {
                object provider = InstantiateProvider(setting);

                if (provider == null)
                    throw new ProviderException(string.Format("初始化 '{0}' 提供程序失败。", setting.Name));

                if (mos.ContainsKey(setting.Name))
                    throw new ProviderException(string.Format("重复的提供程序 '{0}'。", setting.Name));

                mos.Add(setting.Name, provider);
            }

            return mos;
        }

        /// <summary>
        /// 获取已加载提供程序的实例。
        /// </summary>
        /// <param name="Id">提供程序名称。</param>
        /// <returns>提供程序实例，当不存在指定名称的提供程序时，则返回 null。</returns>
        public static object GetModule(string moduleName)
        {
            if (Providers.ContainsKey(moduleName))
                return Providers[moduleName];

            return null;
        }

        /// <summary>
        /// 初始化一个提供程序的实例。
        /// </summary>
        /// <param name="providerSettings">提供程序设置。</param>
        /// <returns>提供程序的实例。</returns>
        public static object InstantiateProvider(ProviderSettings providerSettings)
        {
            object provider = null;

            string typeName = (providerSettings.Type == null) ? null : providerSettings.Type.Trim();

            if (string.IsNullOrEmpty(typeName))
                throw new ConfigurationErrorsException("初始化提供程序失败，请检查配置文件。");

            try
            {
                provider = Activator.CreateInstance(Type.GetType(typeName));
                if (provider is IInitialize)
                    ((IInitialize)provider).Initialize(providerSettings.Name, providerSettings.Parameters);
            }
            catch(Exception ex)
            {
                //throw ex;
                throw new ConfigurationErrorsException(string.Format("不能初始化 '{0}' 类型的实例。", typeName), ex);
            }            

            return provider;
        }

        #endregion
    }
}